package com.chukun.search.controller.house;

import com.chukun.search.base.ApiResponse;
import com.chukun.search.base.RentValueBlock;
import com.chukun.search.base.ServiceMultiResult;
import com.chukun.search.base.ServiceResult;
import com.chukun.search.dto.*;
import com.chukun.search.form.MapSearch;
import com.chukun.search.form.RentSearch;
import com.chukun.search.model.SupportAddress;
import com.chukun.search.services.IAddressService;
import com.chukun.search.services.IHouseService;
import com.chukun.search.services.ISearchService;
import com.chukun.search.services.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

@Controller
public class HouseController {

    @Autowired
    private IAddressService addressService;

    @Autowired
    private IHouseService houseService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ISearchService searchService;
    /**
     * 获取支持城市列表
     * @return
     */
    @GetMapping("address/support/cities")
    @ResponseBody
    public ApiResponse getSupportCities() {
        ServiceMultiResult<SupportAddressDTO> result = addressService.findAllCities();
        if (result.getResultSize() == 0) {
            return ApiResponse.ofStatus(ApiResponse.ResponseStatus.PAGE_NOT_FOUND);
        }
        return ApiResponse.ofMessage(result.getResult());
    }

    /**
     * 获取对应城市支持区域列表
     * @param cityEnName
     * @return
     */
    @GetMapping("address/support/regions")
    @ResponseBody
    public ApiResponse getSupportRegions(@RequestParam(name = "city_name") String cityEnName) {
        ServiceMultiResult<SupportAddressDTO> addressResult = addressService.findAllRegionsByCityName(cityEnName);
        if (addressResult.getResult() == null || addressResult.getTotal() < 1) {
            return ApiResponse.ofStatus(ApiResponse.ResponseStatus.PAGE_NOT_FOUND);
        }
        return ApiResponse.ofMessage(addressResult.getResult());
    }

    /**
     * 获取具体城市所支持的地铁线路
     * @param cityEnName
     * @return
     */
    @GetMapping("address/support/subway/line")
    @ResponseBody
    public ApiResponse getSupportSubwayLine(@RequestParam(name = "city_name") String cityEnName) {
        List<SubwayDTO> subways = addressService.findAllSubwayByCity(cityEnName);
        if (subways.isEmpty()) {
            return ApiResponse.ofStatus(ApiResponse.ResponseStatus.PAGE_NOT_FOUND);
        }
        return ApiResponse.ofMessage(subways);
    }

    /**
     * 获取对应地铁线路所支持的地铁站点
     * @param subwayId
     * @return
     */
    @GetMapping("address/support/subway/station")
    @ResponseBody
    public ApiResponse getSupportSubwayStation(@RequestParam(name = "subway_id") Long subwayId) {
        List<SubwayStationDTO> stationDTOS = addressService.findAllStationBySubway(subwayId);
        if (stationDTOS.isEmpty()) {
            return ApiResponse.ofStatus(ApiResponse.ResponseStatus.PAGE_NOT_FOUND);
        }
        return ApiResponse.ofMessage(stationDTOS);
    }

    @GetMapping("rent/house")
    public String rentHousePage(RentSearch rentSearch, HttpSession session, ModelMap modelMap, RedirectAttributes redirectAttributes){
        if(StringUtils.isEmpty(rentSearch.getCityEnName())){
            String sessionCityName = (String) session.getAttribute("cityEnName");
            if(StringUtils.isEmpty(sessionCityName)){
                redirectAttributes.addAttribute("msg","must_choose_city");
                return "redirect:/index";
            }else{
                rentSearch.setCityEnName(sessionCityName);
            }
        }else{
            session.setAttribute("cityEnName", rentSearch.getCityEnName());
        }

        ServiceResult<SupportAddressDTO> serviceResult = addressService.findCity(rentSearch.getCityEnName());
        if(!serviceResult.isSuccess()){
            redirectAttributes.addAttribute("msg", "must_chose_city");
            return "redirect:/index";
        }
        modelMap.put("currentCity",serviceResult.getResult());
        ServiceMultiResult allRegionsByCityName = addressService.findAllRegionsByCityName(rentSearch.getCityEnName());
        if(allRegionsByCityName.getResult()==null || allRegionsByCityName.getTotal()<1){
            redirectAttributes.addAttribute("msg", "must_chose_city");
            return "redirect:/index";
        }

        ServiceMultiResult<HouseDTO> houseDTOServiceMultiResult = houseService.query(rentSearch);

        modelMap.put("total",houseDTOServiceMultiResult.getTotal());
        modelMap.put("houses",houseDTOServiceMultiResult.getResult());
        if(rentSearch.getCityEnName()==null){
            rentSearch.setCityEnName("*");
        }
        modelMap.put("searchBody",rentSearch);
        modelMap.put("regions",allRegionsByCityName.getResult());
        modelMap.put("priceBlocks", RentValueBlock.PRICE_BLOCK);
        modelMap.put("areaBlocks",RentValueBlock.AREA_BLOCK);
        modelMap.put("currentPriceBlock",RentValueBlock.matchPrice(rentSearch.getPriceBlock()));
        modelMap.put("currentAreaBlock",RentValueBlock.matchPrice(rentSearch.getAreaBlock()));
        return "rent-list";
    }

    @GetMapping("rent/house/show/{id}")
    public String show(@PathVariable(value = "id") Long houseId,
                       Model model) {
        if (houseId <= 0) {
            return "404";
        }

        ServiceResult<HouseDTO> serviceResult = houseService.findHouseByHouseId(houseId);
        if (!serviceResult.isSuccess()) {
            return "404";
        }
        HouseDTO houseDTO = serviceResult.getResult();
        Map<SupportAddress.Level, SupportAddressDTO> cityAndRegion = addressService.findCityAndRegion(houseDTO.getCityEnName(), houseDTO.getRegionEnName());

        SupportAddressDTO city = cityAndRegion.get(SupportAddress.Level.CITY);
        SupportAddressDTO region = cityAndRegion.get(SupportAddress.Level.REGION);

        model.addAttribute("city",city);
        model.addAttribute("region",region);
        ServiceResult<UserDTO> userDTOServiceResult = userService.findById(houseDTO.getAdminId());

        model.addAttribute("agent", userDTOServiceResult.getResult());
        model.addAttribute("house", houseDTO);

        model.addAttribute("houseCountInDistrict", searchService.aggregateDistrictHouse(city.getEnName(),region.getEnName(),houseDTO.getDistrict()));
        return "house-detail";
    }

    /**
     * 自动补全接口
     */
    @GetMapping("rent/house/autocomplete")
    @ResponseBody
    public ApiResponse autocomplete(@RequestParam(value = "prefix") String prefix) {

        if (prefix.isEmpty()) {
            return ApiResponse.ofStatus(ApiResponse.ResponseStatus.BAD_REQUEST);
        }
        ServiceResult<List<String>> result = this.searchService.suggest(prefix);
        return ApiResponse.ofMessage(result.getResult());
    }

    /**
     * 去地图页面，渲染地图需要的数据
     * @param cityEnName
     * @param model
     * @param session
     * @param redirectAttributes
     * @return
     */
    @GetMapping("rent/house/map")
    public String rentMapPage(@RequestParam(value = "cityEnName") String cityEnName,
                              Model model,
                              HttpSession session,
                              RedirectAttributes redirectAttributes){
        ServiceResult<SupportAddressDTO>city = addressService.findCity(cityEnName);
        if (!city.isSuccess()) {
            redirectAttributes.addAttribute("msg", "must_chose_city");
            return "redirect:/index";
        } else {
            session.setAttribute("cityName", cityEnName);
            model.addAttribute("city", city.getResult());
        }
        ServiceMultiResult allRegions = addressService.findAllRegionsByCityName(cityEnName);

        ServiceMultiResult<HouseBucketDTO> serviceResult =searchService.mapAggregation(cityEnName);

        model.addAttribute("aggData", serviceResult.getResult());
        model.addAttribute("total", serviceResult.getTotal());
        model.addAttribute("regions", allRegions.getResult());
        return "rent-map";
    }

    /**
     * 地图区域房源查询
     * @param mapSearch
     * @return
     */
    @GetMapping("rent/house/map/houses")
    @ResponseBody
    public ApiResponse rentMapHouse(MapSearch mapSearch){
        if(mapSearch.getCityEnName()==null){
            return ApiResponse.ofMessage(HttpStatus.BAD_REQUEST.value(), "必须选择城市");
        }
        ServiceMultiResult<HouseDTO> serviceMultiResult;
        if(mapSearch.getLevel()<13){
            serviceMultiResult = houseService.wholeMapQuery(mapSearch);
        }else{
            //小地图查询，需要传递边界参数
            serviceMultiResult = houseService.boundMapQuery(mapSearch);
        }
        ApiResponse response = ApiResponse.ofMessage(serviceMultiResult.getResult());
        response.setMore(serviceMultiResult.getTotal() > (mapSearch.getStart() + mapSearch.getSize()));
        return response;
    }

}
